import 'dart:math';

import 'package:acgn_pioneer/models/chapter_slot_model.dart';
import 'package:acgn_pioneer/widgets/reader/_index.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';

import '../../public.dart';
import 'barrage/_index.dart';
import 'events/_index.dart';
import 'mixins/_index.dart';

abstract class ReaderBase<T extends StatefulWidget> extends State
    with ReaderWidgetBase {
  /// 触摸起始点位置
  double start = 0;

  /// 触摸点横\纵坐标
  double touchX = 0;
  double touchY = 0;

  /// 是否向下
  bool isNextDirection = false;

  /// 是否清理中
  bool isClearing = false;

  /// 章节信息预判断距离
  double imageSwitchDistance = 0;

  /// 章节请求loading
  bool loadingChapterApi = false;

  /// 漫画请求loading
  bool loadingComicApi = false;

  /// 视区图片的上下2张范围内的优先进行预加载
  int preloadScope = 2;

  ScrollController scrollController = ScrollController();

  var sub; // 章节图片加载改变
  var subRedirectChapter; // 章节跳转
  var subDetail; // 头部详情加载结束（用来发送事件，更新slot详情实际高度）

  @override
  void initState() {
    super.initState();
    sub = readerPage.bus.on<ReaderImageLoadEvent>().listen((event) {
      if (readModel.chapterListMap[event.model.chapterId] == null) {
        return;
      }
      imgLoadSucc(event.model);
    });

    subRedirectChapter =
        readerPage.bus.on<ReaderRedirectChapterIndexEvent>().listen((event) {
      initChapter(event.chapterId);
    });

    subDetail =
        readerPage.bus.on<ReaderChapterDetailSlotEvent>().listen((event) {
      var slot = readModel.chapterImageList[0].slots
          .firstWhere((item) => item.type == ReaderSlotType.detail);
      slot.height = event.size.height;
      updateDistance();
    });

    initData();
  }

  @override
  void dispose() {
    sub.cancel();
    subDetail.cancel();
    subRedirectChapter.cancel();
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (readModel.currentChapter == null ||
        readModel.currentChapter.comicModel.isNoCopyright) {
      return Container();
    }
    return buildView();
  }

  initData() async {
    await initComicData(readModel.comicId, readModel.chapterId, record: true);
    readerPage.bus.fire(ReaderRunEvent());
  }

  /// 跳转指定章节
  initChapter(int chapterId) async {
    scrollController.jumpTo(0);
    readModel.chapterImageList.clear();
    readModel.currentImageIndex = 1;
    await initComicData(readModel.comicId, chapterId,
        initComic: false, record: true);
    readerPage.bus.fire(ReaderChapterIndexChangeEvent());
  }

  /// 初始化漫画数据
  initComicData(int comicId, int initChapterId,
      {bool record = false, initComic = true}) async {
    if (loadingComicApi) {
      return;
    }
    loadingComicApi = true;
    if (initComic) {
      ComicModel comic = await readerPage.comicService.getComicData(comicId);
      if (comic.isNoCopyright) {
        readModel.currentChapter = ChapterModel(comicModel: comic);
        readModel.isLoadCompleted = true;
        refreshView();
        return;
      }
      if (initChapterId == null) {
        /// 如果没有传入初始章节ID，表示连续加载下一部漫画，则取漫画第一章
        initChapterId = comic.chapters[0].id;
      }
      readerPage.comicService.installChapterRelation(comic.chapters);
    }
    var chapter = readModel.chapterListMap[initChapterId];
    var tempList = await getChapterData(initChapterId);

    if (readModel.isPopNested) {
      tempList[0].slots.add(ChapterSlotModel(
          width: readModel.screenWidth,
          height: 100,
          type: ReaderSlotType.topClose,
          isBefore: true));
    }

    /// 章节头部第一张图片中加入详情的插槽
    tempList[0].slots.add(ChapterSlotModel(
        width: readModel.screenWidth,
        height: Rem(404),
        type: ReaderSlotType.detail,
        data: readModel.chapterListMap[initChapterId],
        isBefore: true));

    if (record) {
      readModel.currentChapter = chapter;
      readModel.isLoadCompleted = true;
    }
    refreshView();
    loadingComicApi = false;
  }

  /// 设置章节图片信息
  List<ChapterImageModel> setImageList(
      ChapterModel chapter, List<dynamic> imgList,
      {bool isBefore = false}) {
    List<ChapterImageModel> tempList = [];
    var len = imgList.length;
    List<ChapterBarrageModel> lst = [];
    for (var i = 0; i < len; i++) {
      var imgModel = ChapterImageModel.fromModel(
          chapter.id, imgList[i], i + 1, i == len - 1);
      tempList.add(imgModel);

      // 添加测试弹幕数据
      // for (var j = 0; j < 10; j++) {
      //   lst.add(ChapterBarrageModel(
      //       chapterId: chapter.id,
      //       imageIndex: imgModel.index,
      //       text: chapter.comicModel.name +
      //           j.toString() +
      //           '---哈哈' +
      //           chapter.id.toString() +
      //           '/' +
      //           imgModel.index.toString()));
      // }
    }
    readerPage.barrageController.saveModel(lst);
    chapter.totalPage = len;
    readModel.chapterImageList
        .insertAll(isBefore ? 0 : readModel.chapterImageList.length, tempList);
    updateDistance();
    return tempList;
  }

  /// 下一章
  Future<bool> getNextChapter() async {
    int nextChapterId = readModel.currentChapter.nextId;
    if (this.validChapterAndUpdateQueue(nextChapterId)) {
      return false;
    }
    await getChapterData(nextChapterId);
    return true;
  }

  // 上一章
  Future<void> getPrevChapter() async {
    int prevChapterId = readModel.currentChapter.prevId;
    if (this.validChapterAndUpdateQueue(prevChapterId)) {
      return null;
    }

    var list = getChapterData(prevChapterId, isBefore: true);
    // 向上加载，需要把当前index顺位往后延
    readModel.currentImageIndex += list.length;
  }

  getChapterData(chapterId, {isBefore = false}) async {
    this.loadingChapterApi = true;
    var chapter = readModel.chapterListMap[chapterId];
    List<dynamic> imgList = await readerPage.chapterService
        .getChapterData(chapter.comicModel.id, chapterId);
    var list = setImageList(chapter, imgList, isBefore: isBefore);
    chapter.isInited = true;
    this.loadingChapterApi = false;
    getChapterBarrage(chapter);
    return list;
  }

  /// 获取章节弹幕
  getChapterBarrage(ChapterModel chapter) async {
    var list = await readerPage.barrageService.getChapterBarrage(chapter);
    readerPage.barrageController.saveModel(list);
    setState(() {});
  }

  /// 效验是否为有效请求
  bool validChapterAndUpdateQueue(int chapterId) {
    /// 章节id无效
    if (chapterId == null) {
      return true;
    }

    /// 章节已经加载过
    if (readModel.chapterListMap[chapterId].isInited) {
      return true;
    }

    /// 当前请求队列正在请求中
    if (this.loadingChapterApi) {
      // ACGN.toast.message('请求中...');
      return true;
    }
    return false;
  }

  updateDistance() {
    double endDistance = 0;
    readModel.chapterImageList.forEach((image) {
      endDistance += this.getPerDistance(image);
      image.endDistance = endDistance;
    });
    readModel.totalDistance = endDistance;
  }

  Widget itemBuilder(BuildContext context, int index) {
    var img = readModel.chapterImageList[index];
    preLoadImage(img); // 进入视窗，优先加载
    List<Widget> widgets = []; // 一个item中的组件集合（前后slots + img）

    /// 前置slots
    installSlotItems(
        img.slots.where((element) => element.isBefore).toList(), widgets);

    /// 图片节点
    installImgItem(img, widgets);

    /// 后置slots
    installSlotItems(
        img.slots.where((element) => !element.isBefore).toList(), widgets);

    return Column(
      children: widgets,
    );
  }

  installImgItem(ChapterImageModel img, List<Widget> widgets) {
    if (!img.isSucceed) {
      widgets.add(Container(
          decoration: BoxDecoration(color: Color(0xff1B1B26)),
          width: readModel.screenWidth,
          height: readModel.screenHeight,
          child: Center(
              child: img.faileCount > 0
                  ? buildFailImage(img)
                  : Text(
                      img.index.toString(),
                      style: TextStyle(fontSize: 60, color: Color(0x4cffffff)),
                    ))));
    } else {
      widgets.add(Container(
          width: img.showWidth,
          height: img.showHeight,
          child: Stack(
            children: [
              Positioned.fill(child: RawImage(image: img.dom.image)),
              isCurrentComic()
                  ? Positioned.fill(
                      child: ReaderBarrageMain(
                      index: img.index,
                      chapterId: img.chapterId,
                      height: img.showHeight / 2,
                    ))
                  : SizedBox.shrink()
            ],
          )));
    }
  }

  isCurrentComic() {
    return true;
    return readModel.currentChapter.comicModel.id ==
        readerMainPage.comicIds[readerMainPage.currentPageIndex];
  }

  installSlotItems(List<ChapterSlotModel> slots, List<Widget> widgets) {
    slots.forEach((ele) {
      switch (ele.type) {
        case ReaderSlotType.topClose:
          widgets.add(buildPopClose());
          break;
        case ReaderSlotType.detail:
          widgets.add(ReaderDetail(data: ele.data));
          break;
        case ReaderSlotType.interact:
          break;
        case ReaderSlotType.advert:
          break;
        case ReaderSlotType.end:
          widgets.add(ReaderDetail());
          break;
      }
    });
  }

  buildPopClose() {
    return GestureDetector(
      onTap: () {
        Navigator.pop(context);
      },
      child: Container(
          padding: EdgeInsets.only(right: 20),
          alignment: Alignment.centerRight,
          height: 16,
          child: SVG.icon('close', color: Colors.white)),
    );
  }

  buildFailImage(ChapterImageModel img) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        SVG.svg('no_comm', width: 150, height: 110),
        Text(
          '图片加载失败啦，呜呜~',
          style: TextStyle(color: Color(0x99ffffff), fontSize: 12),
        ),
        SizedBox(height: Rem(16)),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(
              color: Color(0x4c525273),
              onPressed: () {
                console('cli-反馈');
              },
              child: Text(
                '反馈',
                style: TextStyle(fontSize: 14, color: Color(0x99ffffff)),
              ),
              shape: RoundedRectangleBorder(
                  side: BorderSide.none,
                  borderRadius: BorderRadius.all(Radius.circular(16))),
            ),
            SizedBox(width: Rem(24)),
            RaisedButton(
              color: Color(0x4c525273),
              onPressed: () {
                img.isInited = false;
                img.isCreateDom = false;
                setState(() {});
              },
              child: Text(
                '重试',
                style: TextStyle(fontSize: 14, color: Color(0x99ffffff)),
              ),
              shape: RoundedRectangleBorder(
                  side: BorderSide.none,
                  borderRadius: BorderRadius.all(Radius.circular(16))),
            )
          ],
        )
      ],
    );
  }

  /// 清除上一部漫画数据
  void clearPreComic() {
    if (this.isClearing) {
      return;
    }
    this.isClearing = true;

    readerMainPage.toNextComicPage();
    scrollController.jumpTo(0);
    this.isClearing = false;
  }

  void updateCurrentChapter(double offset) async {
    var imgList = readModel.chapterImageList;
    var currentDistance = min(offset, imgList[imgList.length - 1].endDistance);
    if (readModel.comicLastDistance != 0 &&
        offset > readModel.comicLastDistance) {
      clearPreComic();
      return;
    }

    ChapterImageModel currentImg;
    try {
      currentImg = readModel.chapterImageList.firstWhere((img) {
        return img.endDistance > currentDistance + imageSwitchDistance;
      });
    } catch (ex) {
      return;
    }
    var curentChapter = readModel.chapterListMap[currentImg.chapterId];

    // 切换当前章节记录
    if (readModel.currentChapter != curentChapter) {
      this.setCurrentChapter(curentChapter);
      readerPage.bus.fire(ReaderChapterIndexChangeEvent());
    }

    if (readModel.currentImageIndex != currentImg.index) {
      this.setCurrentChapterIndex(currentImg.index);
      readerPage.bus.fire(ReaderChapterImageIndexChangeEvent(currentImg));
    }
    addUserRead();

    if (isNextDirection &&
        readModel.currentChapter.totalPage - readModel.currentImageIndex <= 3) {
      bool re = await getNextChapter();
      if (re) {
        updateView();
      }
      // return;
    }
    if (!readModel.hasGetNextComic &&
        isNextDirection &&
        curentChapter.comicModel.lastChapterId == curentChapter.id) {
      var tempIds = readerMainPage.comicIds;
      var index = tempIds.indexOf(readModel.comicId);
      if (index + 1 < tempIds.length) {
        initComicData(tempIds[index + 1], null);
        readModel.hasGetNextComic = true;
        ACGN.toast.message('加载新漫画...');
      }
      ACGN.toast.message('已经最后一章了...');
    }
    // if (!isNextDirection && readerPage.state.index <= 3) {
    //   await readerPage.getPrevChapter();
    //   updateView();
    // }
  }

  void updateView() {
    setState(() {});
  }

  void preLoadImage(ChapterImageModel img) {
    if (img.isCreateDom) {
      return;
    }

    if (img.isSucceed) {
      installResizeImg(img);
      img.isCreateDom = true;
      return;
    }
    img.isObserved = true;

    /// 图片正在加载中
    if (img.isInited) {
      return;
    }
    img.priority = 2;
    preLoadScopeImage(img);
    readerPage.imageLoaderService.loadImageBatch();
  }

  // 预加载视区指定上下范围的图片
  preLoadScopeImage(img) {
    var imgList = readModel.chapterImageList;
    var index = imgList.indexOf(img);
    var start = max(index - preloadScope, 0);
    var end = min(index + preloadScope, imgList.length - 1);
    for (var i = start; i <= end; i++) {
      var img = imgList[i];

      /// 如果图片已经观察结束
      if (img.isObserved) {
        continue;
      }
      img.priority = 1;
    }
  }

  void imgLoadSucc(ChapterImageModel img) {
    if (img.isSucceed) {
      installResizeImg(img);
      img.isCreateDom = true;
    }

    updateDistance();
    updateLastDistance(img.chapterId);
    if (img.priority == 2 || img.isObserved) {
      updateView();
    }
  }

  void updateLastDistance(int chapterId) {
    var comic = readModel.chapterListMap[chapterId].comicModel;
    var lastImgList = readModel.chapterImageList
        .where((item) => item.chapterId == comic.lastChapterId)
        .toList();
    var lastLen = lastImgList.length;
    if (lastLen > 0) {
      readModel.comicLastDistance = lastImgList[lastLen - 1].endDistance;
    }
  }

  void setCurrentChapter(ChapterModel curentChapter) {
    readModel.currentChapter = curentChapter;
  }

  // 添加阅读历史
  addUserRead() {
    if (readModel.currentChapter.isPostRead || user.type == 'device') {
      return;
    }
    readModel.currentChapter.isPostRead = true;
    readerPage.chapterService.addUserRead(
        readModel.currentChapter, readModel.currentImageIndex, user.uid);
  }

  void setCurrentChapterIndex(index) {
    readModel.currentImageIndex = index;
  }

  Widget buildView() {
    throw 'buildView not implements';
  }

  void installResizeImg(ChapterImageModel sourceImage) {
    throw 'installResizeImg not implements';
  }

  // 获取每个图片展示距离
  double getPerDistance(ChapterImageModel sourceImage) {
    throw 'getPerDistance not implements';
  }
}
